Drag and drop

Otázka od: Pavel Poles

31. 10. 2003 17:55

Zdravim konferenci,

potreboval bych poradit s operaci drag and drop.
Rekneme ze mam panel na kterem jsou umisteny nejake (nevim jake)
TControls (resp. jejich seznam dokazu ziskat, ale mohou byt jakehokoliv
typu).
Zanu operaci dragovani a nyni bych potreboval, aby mi DragOver chodilo stale
do toho panelu, i kdyz pojedu mysi pres controls na nem umistene....
To vse samozrejme bez upravy zdrojaku tech controls, tak aby to bylo
obecne...

Jedna se o CLX aplikaci

Prosim o radu, jsem uz zoufaly

Diky

Pavel Poles





----------
* www.inMail.sk - Vasa emailova adresa na cely zivot ZDARMA
* Mail neobsahuje virusy. Zkontrolovane antivirusom NOD32 (www.eset.sk)
* www.SlovakNET.sk - profesionalny webhosting, domena .SK ZADARMO
* Zoner Media Explorer 5 - stiahnite si pomocnika pre digitalnu fotografiu
(zme.zoner.sk)

Odpovedá: Peter Ondras

2. 11. 2002 11:28

(*
Vytvor novu aplikaciu, daj na formular jeden (pre tento priklad Button, ale
prakticky mozes pouzit ktorukolvek vizualnu komponentu Delphi, ale potom
nezabudni patricne prerobit kod tohto programu. Cize nezabudni prepisat TButton
na napr. TEdit pre Edit atd.). Po pridani Buttonu na form nastav jeho
OnMouseDown na ButtonMouseDown, OnMouseMove na ButtonMouseMove a OnMouseUp na
ButtonMouseUp. Udalost form OnShow nastav na FormShow. Nova poloha Buttonu sa
ulozi a pri novom nacitani programu sa premiestni na svoje nove miesto. V
pripade problemov alebo dalsich poziadaviek (univerzalny save a load na vsetky
komponenty a pod. ma kontaktuj priamo na moj mail peter.ondras@pse.sk.
Nezabudni, ze komponenta sa da presuvat len v ramci svojej Parent komponenty.
Cize ak je priamo na formulari tak ju mozes presuvat po celom formulari. Ak je
napr. na oblasti panelu, tak ju nepohnes inde ako na oblasti, ktora patri
panelu. Resp. pohnes ju do minusovych alebo prilis plusovych hodnot. Napr. na -
500 pre vlatnost TOP, co logicky znemena, ze komponenta nebude viditelna
(viditelna oblast sa zacina nulou pre TOP aj LEFT).
*)

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormShow(Sender: TObject);
    procedure ButtonMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure ButtonMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure ButtonMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    Dragging: Boolean;
    XOffSet, YOffSet: Integer;
    FocusRect: TRect;
    MyButton: TButton;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ButtonMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  Dragging:=True;
  XOffSet:=X; YOffSet:=Y;
  MyButton:=Sender as TButton;
  with MyButton do begin
    FocusRect:=Rect(Left,Top,Left+Width,Top+Height);
    Canvas.DrawFocusRect(FocusRect);
  end;
end;

procedure TForm1.ButtonMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
begin
  if Dragging then
    begin
      Canvas.DrawFocusRect(FocusRect);
      with FocusRect do begin
        Left:=(MyButton.Left+X)-XOffSet;
        Top:=(MyButton.Top+Y)-YOffSet;
        Right:=MyButton.Width+Left;
        Bottom:=MyButton.Height+Top;
      end;
     Canvas.DrawFocusRect(FocusRect);
    end;
end;

procedure TForm1.ButtonMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
Var Stream: TFileStream;
begin
  if Dragging then
    begin
      Canvas.DrawFocusRect(FocusRect);
      Dragging:=False;
      with Sender as TButton do begin
        Left:=(Left+X)-XOffSet;
        Top:=(Top+Y)-YOffSet;
        Stream:=TFileStream.Create('components.dat', fmCreate);
        try
          Stream.WriteComponent(Button1);
        finally
          Stream.Free;
        end;
      end;
    end;
end;

procedure TForm1.FormShow(Sender: TObject);
var Stream: TFileStream;
begin
  if FileExists('components.dat') then
    begin
      Stream:=TFileStream.Create('components.dat', fmOpenRead);
      try
        Stream.ReadComponent(Button1);
      finally
        Stream.Free;
      end;
    end;
end;

end.

Peter Ondras
peter.ondras@pse.sk
(+421) 0904 421 925


>: -----Original Message-----
>: From: delphi-l-owner@clexpert.cz [mailto:delphi-l-owner@clexpert.cz] On
>: Behalf Of Martin Kasman
>: Sent: Thursday, October 31, 2002 6:55 PM
>: To: Delphi
>: Subject: Drag and drop
>:
>: D6, WinXP
>:
>: Potrebujem v programe spravit drag and drop s labelom: teda, aby sa dalo
>: kliknut na label, potiahnut a pustit. Label ostane na svojom novom
>: mieste.
>:
>: Cez zabudovane funkcie DragMode to vobec neviem urobit, a ak to robim cez
>: onMouseMove, tak ziskavam z premennej X a Y zvlastne hodnoty, ktore sa
>: stale
>: menia aj ked s mysou nepohybujem.
>:
>: Vdaka za kazdu radu.
>:
>:
>: --------------------
>: tisicky obrazkov na tlacitka a ikonky - www.martinkasman.host.sk

Odpovedá: Martin Kasman

3. 11. 2002 0:36

Funguje to skvele, no pokial je komponenta na inej komponente (napr. Button
na Panely), tak pri vykreslovani FocusRect ho nie je vidno, pretoze je
vykreslovany na form pod tu kompronentu (napr. pod Panelom). Co s tym?

A ozaj preco sa na zaciatku musi vytvorit ten Stream, ked sa vzapeti na to
maze?

----- Original Message -----
From: "Peter Ondras" <peter.ondras@pse.sk>


> unit Unit1;
>
> interface
>
> uses
> Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
> Dialogs, StdCtrls;
>
> type
> TForm1 = class(TForm)
> Button1: TButton;
> procedure FormShow(Sender: TObject);
> procedure ButtonMouseDown(Sender: TObject; Button: TMouseButton;
> Shift: TShiftState; X, Y: Integer);
> procedure ButtonMouseMove(Sender: TObject; Shift: TShiftState; X,
> Y: Integer);
> procedure ButtonMouseUp(Sender: TObject; Button: TMouseButton;
> Shift: TShiftState; X, Y: Integer);
> private
> Dragging: Boolean;
> XOffSet, YOffSet: Integer;
> FocusRect: TRect;
> MyButton: TButton;
> public
> { Public declarations }
> end;
>
> var
> Form1: TForm1;
>
> implementation
>
> {$R *.dfm}
>
> procedure TForm1.ButtonMouseDown(Sender: TObject;
> Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
> begin
> Dragging:=True;
> XOffSet:=X; YOffSet:=Y;
> MyButton:=Sender as TButton;
> with MyButton do begin
> FocusRect:=Rect(Left,Top,Left+Width,Top+Height);
> Canvas.DrawFocusRect(FocusRect);
> end;
> end;
>
> procedure TForm1.ButtonMouseMove(Sender: TObject; Shift: TShiftState;
> X, Y: Integer);
> begin
> if Dragging then
> begin
> Canvas.DrawFocusRect(FocusRect);
> with FocusRect do begin
> Left:=(MyButton.Left+X)-XOffSet;
> Top:=(MyButton.Top+Y)-YOffSet;
> Right:=MyButton.Width+Left;
> Bottom:=MyButton.Height+Top;
> end;
> Canvas.DrawFocusRect(FocusRect);
> end;
> end;
>
> procedure TForm1.ButtonMouseUp(Sender: TObject; Button: TMouseButton;
> Shift: TShiftState; X, Y: Integer);
> Var Stream: TFileStream;
> begin
> if Dragging then
> begin
> Canvas.DrawFocusRect(FocusRect);
> Dragging:=False;
> with Sender as TButton do begin
> Left:=(Left+X)-XOffSet;
> Top:=(Top+Y)-YOffSet;
> Stream:=TFileStream.Create('components.dat', fmCreate);
> try
> Stream.WriteComponent(Button1);
> finally
> Stream.Free;
> end;
> end;
> end;
> end;
>
> procedure TForm1.FormShow(Sender: TObject);
> var Stream: TFileStream;
> begin
> if FileExists('components.dat') then
> begin
> Stream:=TFileStream.Create('components.dat', fmOpenRead);
> try
> Stream.ReadComponent(Button1);
> finally
> Stream.Free;
> end;
> end;
> end;
>
> end.
>
> Peter Ondras

Odpovedá: Lubos Urban

4. 11. 2002 19:29

Toto som raz davno nasiel na borlandackych newsoch:

Question: How can I move a control at runtime using the mouse?

Answer: You can trap the OnMouseDown event, remembering the x and y
coordinates of the mouse
        and set the mouse capture. You can then track mouse movements with
the OnMouseMove event,
        moving the control until the OnMouseUp event is fired. You then will
want to place the
        control in it's final position and release capture of the mouse.
        The following example shows how to move a TButton component around
on the form using
        the mouse. The movement is initiated by the user holding down the
control key when the
        mouse button is activated.
Example:
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Button1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure Button1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
    MouseDownSpot : TPoint;
    Capturing : bool;
  end;
var
  Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if ssCtrl in Shift then begin
    SetCapture(Button1.Handle);
    Capturing := true;
    MouseDownSpot.X := x;
    MouseDownSpot.Y := Y;
  end;
end;
procedure TForm1.Button1MouseMove(Sender: TObject;
Shift: TShiftState; X, Y: Integer);
begin
  if Capturing then begin
    Button1.Left := Button1.Left - (MouseDownSpot.x - x);
    Button1.Top := Button1.Top - (MouseDownSpot.y - y);
  end;
end;
procedure TForm1.Button1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if Capturing then begin
    ReleaseCapture;
    Capturing := false;
    Button1.Left := Button1.Left - (MouseDownSpot.x - x);
    Button1.Top := Button1.Top - (MouseDownSpot.y - y);
  end;
end;

----- Original Message -----
From: "Martin Kasman" <martinkasman@centrum.sk>
To: "Delphi" <delphi-l@clexpert.cz>
Sent: Thursday, October 31, 2002 6:54 PM
Subject: Drag and drop

> D6, WinXP
>
> Potrebujem v programe spravit drag and drop s labelom: teda, aby sa dalo
> kliknut na label, potiahnut a pustit. Label ostane na svojom novom mieste.
>
> Cez zabudovane funkcie DragMode to vobec neviem urobit, a ak to robim cez
> onMouseMove, tak ziskavam z premennej X a Y zvlastne hodnoty, ktore sa
stale
> menia aj ked s mysou nepohybujem.
>
> Vdaka za kazdu radu.
>
>
> --------------------
> tisicky obrazkov na tlacitka a ikonky - www.martinkasman.host.sk
>
>
>
>

Odpovedá: Peter Ondras

4. 11. 2002 21:42

No to neviem. S tym som si nevedel vobec poradit. Mozno by bolo dobre
nevykreslovat focus vobec a problem by bol svojim sposobom vyrieseny  .
Iny sposob ma prave nenapada.

Peter Ondras
peter.ondras@pse.sk
(+421) 0904 421 925

>: -----Original Message-----
>: From: delphi-l-owner@clexpert.cz [mailto:delphi-l-owner@clexpert.cz]
On
>: Behalf Of Martin Kasman
>: Sent: Saturday, November 02, 2002 11:26 PM
>: To: delphi-l@clexpert.cz
>: Subject: Re: Drag and drop
>:
>: Funguje to skvele, no pokial je komponenta na inej komponente (napr.
>: Button
>: na Panely), tak pri vykreslovani FocusRect ho nie je vidno, pretoze
je
>: vykreslovany na form pod tu kompronentu (napr. pod Panelom). Co s
tym?
>:
>: A ozaj preco sa na zaciatku musi vytvorit ten Stream, ked sa vzapeti
na
>: to
>: maze?
>:
>: ----- Original Message -----
>: From: "Peter Ondras" <peter.ondras@pse.sk>
>:
>:
>: > unit Unit1;
>: >
>: > interface
>: >
>: > uses
>: > Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls,
>: Forms,
>: > Dialogs, StdCtrls;
>: >
>: > type
>: > TForm1 = class(TForm)
>: > Button1: TButton;
>: > procedure FormShow(Sender: TObject);
>: > procedure ButtonMouseDown(Sender: TObject; Button:
TMouseButton;
>: > Shift: TShiftState; X, Y: Integer);
>: > procedure ButtonMouseMove(Sender: TObject; Shift: TShiftState;
X,
>: > Y: Integer);
>: > procedure ButtonMouseUp(Sender: TObject; Button: TMouseButton;
>: > Shift: TShiftState; X, Y: Integer);
>: > private
>: > Dragging: Boolean;
>: > XOffSet, YOffSet: Integer;
>: > FocusRect: TRect;
>: > MyButton: TButton;
>: > public
>: > { Public declarations }
>: > end;
>: >
>: > var
>: > Form1: TForm1;
>: >
>: > implementation
>: >
>: > {$R *.dfm}
>: >
>: > procedure TForm1.ButtonMouseDown(Sender: TObject;
>: > Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
>: > begin
>: > Dragging:=True;
>: > XOffSet:=X; YOffSet:=Y;
>: > MyButton:=Sender as TButton;
>: > with MyButton do begin
>: > FocusRect:=Rect(Left,Top,Left+Width,Top+Height);
>: > Canvas.DrawFocusRect(FocusRect);
>: > end;
>: > end;
>: >
>: > procedure TForm1.ButtonMouseMove(Sender: TObject; Shift:
TShiftState;
>: > X, Y: Integer);
>: > begin
>: > if Dragging then
>: > begin
>: > Canvas.DrawFocusRect(FocusRect);
>: > with FocusRect do begin
>: > Left:=(MyButton.Left+X)-XOffSet;
>: > Top:=(MyButton.Top+Y)-YOffSet;
>: > Right:=MyButton.Width+Left;
>: > Bottom:=MyButton.Height+Top;
>: > end;
>: > Canvas.DrawFocusRect(FocusRect);
>: > end;
>: > end;
>: >
>: > procedure TForm1.ButtonMouseUp(Sender: TObject; Button:
TMouseButton;
>: > Shift: TShiftState; X, Y: Integer);
>: > Var Stream: TFileStream;
>: > begin
>: > if Dragging then
>: > begin
>: > Canvas.DrawFocusRect(FocusRect);
>: > Dragging:=False;
>: > with Sender as TButton do begin
>: > Left:=(Left+X)-XOffSet;
>: > Top:=(Top+Y)-YOffSet;
>: > Stream:=TFileStream.Create('components.dat', fmCreate);
>: > try
>: > Stream.WriteComponent(Button1);
>: > finally
>: > Stream.Free;
>: > end;
>: > end;
>: > end;
>: > end;
>: >
>: > procedure TForm1.FormShow(Sender: TObject);
>: > var Stream: TFileStream;
>: > begin
>: > if FileExists('components.dat') then
>: > begin
>: > Stream:=TFileStream.Create('components.dat', fmOpenRead);
>: > try
>: > Stream.ReadComponent(Button1);
>: > finally
>: > Stream.Free;
>: > end;
>: > end;
>: > end;
>: >
>: > end.
>: >
>: > Peter Ondras
>:



----------
Teraz si uz KAZDY moze registrovat svoju domenu .SK
Viac info na: http://www.SlovakNET.sk/predregistracia.asp

Odpovedá: Peter Ondras

4. 11. 2002 21:49

Este ma napadla jedna finta s tym focusom. Objekt CANVAS na ktory sa
odkjazujem je globalny a patri priamo formularu. Mozno by stacilo urobit
PANEL1.CANVAS..... ale neskusal som to.

Peter Ondras
peter.ondras@pse.sk
(+421) 0904 421 925

>: -----Original Message-----
>: From: delphi-l-owner@clexpert.cz [mailto:delphi-l-owner@clexpert.cz]
On
>: Behalf Of Martin Kasman
>: Sent: Saturday, November 02, 2002 11:26 PM
>: To: delphi-l@clexpert.cz
>: Subject: Re: Drag and drop
>:
>: Funguje to skvele, no pokial je komponenta na inej komponente (napr.
>: Button
>: na Panely), tak pri vykreslovani FocusRect ho nie je vidno, pretoze
je
>: vykreslovany na form pod tu kompronentu (napr. pod Panelom). Co s
tym?
>:
>: A ozaj preco sa na zaciatku musi vytvorit ten Stream, ked sa vzapeti
na
>: to
>: maze?
>:
>: ----- Original Message -----
>: From: "Peter Ondras" <peter.ondras@pse.sk>
>:
>:
>: > unit Unit1;
>: >
>: > interface
>: >
>: > uses
>: > Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls,
>: Forms,
>: > Dialogs, StdCtrls;
>: >
>: > type
>: > TForm1 = class(TForm)
>: > Button1: TButton;
>: > procedure FormShow(Sender: TObject);
>: > procedure ButtonMouseDown(Sender: TObject; Button:
TMouseButton;
>: > Shift: TShiftState; X, Y: Integer);
>: > procedure ButtonMouseMove(Sender: TObject; Shift: TShiftState;
X,
>: > Y: Integer);
>: > procedure ButtonMouseUp(Sender: TObject; Button: TMouseButton;
>: > Shift: TShiftState; X, Y: Integer);
>: > private
>: > Dragging: Boolean;
>: > XOffSet, YOffSet: Integer;
>: > FocusRect: TRect;
>: > MyButton: TButton;
>: > public
>: > { Public declarations }
>: > end;
>: >
>: > var
>: > Form1: TForm1;
>: >
>: > implementation
>: >
>: > {$R *.dfm}
>: >
>: > procedure TForm1.ButtonMouseDown(Sender: TObject;
>: > Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
>: > begin
>: > Dragging:=True;
>: > XOffSet:=X; YOffSet:=Y;
>: > MyButton:=Sender as TButton;
>: > with MyButton do begin
>: > FocusRect:=Rect(Left,Top,Left+Width,Top+Height);
>: > Canvas.DrawFocusRect(FocusRect);
>: > end;
>: > end;
>: >
>: > procedure TForm1.ButtonMouseMove(Sender: TObject; Shift:
TShiftState;
>: > X, Y: Integer);
>: > begin
>: > if Dragging then
>: > begin
>: > Canvas.DrawFocusRect(FocusRect);
>: > with FocusRect do begin
>: > Left:=(MyButton.Left+X)-XOffSet;
>: > Top:=(MyButton.Top+Y)-YOffSet;
>: > Right:=MyButton.Width+Left;
>: > Bottom:=MyButton.Height+Top;
>: > end;
>: > Canvas.DrawFocusRect(FocusRect);
>: > end;
>: > end;
>: >
>: > procedure TForm1.ButtonMouseUp(Sender: TObject; Button:
TMouseButton;
>: > Shift: TShiftState; X, Y: Integer);
>: > Var Stream: TFileStream;
>: > begin
>: > if Dragging then
>: > begin
>: > Canvas.DrawFocusRect(FocusRect);
>: > Dragging:=False;
>: > with Sender as TButton do begin
>: > Left:=(Left+X)-XOffSet;
>: > Top:=(Top+Y)-YOffSet;
>: > Stream:=TFileStream.Create('components.dat', fmCreate);
>: > try
>: > Stream.WriteComponent(Button1);
>: > finally
>: > Stream.Free;
>: > end;
>: > end;
>: > end;
>: > end;
>: >
>: > procedure TForm1.FormShow(Sender: TObject);
>: > var Stream: TFileStream;
>: > begin
>: > if FileExists('components.dat') then
>: > begin
>: > Stream:=TFileStream.Create('components.dat', fmOpenRead);
>: > try
>: > Stream.ReadComponent(Button1);
>: > finally
>: > Stream.Free;
>: > end;
>: > end;
>: > end;
>: >
>: > end.
>: >
>: > Peter Ondras
>:



----------
Teraz si uz KAZDY moze registrovat svoju domenu .SK
Viac info na: http://www.SlovakNET.sk/predregistracia.asp